garmin_xt.cc
gdb.cc
geojson.cc
- ggv_bin.cc
- ggv_ovl.cc
globalsat_sport.cc
gpssim.cc
gtm.cc
gbser_private.h
gdb.h
geojson.h
- ggv_bin.h
globalsat_sport.h
gpx.h
grtcirc.h
garmin_xt.cc \
gdb.cc \
geojson.cc \
- ggv_bin.cc \
- ggv_ovl.cc \
globalsat_sport.cc \
gpssim.cc \
gtm.cc \
gbser_private.h \
gdb.h \
geojson.h \
- ggv_bin.h \
globalsat_sport.h \
gpx.h \
grtcirc.h \
--- /dev/null
+/*
+
+ Handle Geogrid-Viewer binary overlay file format (.ovl)
+
+ Copyright (C) 2016-2020 Ralf Horstmann <ralf@ackstorm.de>
+ Copyright (C) 2016-2020 Robert Lipe, robertlipe+source@gpsbabel.org
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <QByteArray>
+#include <QDataStream>
+#include <QDebug>
+#include <QFile>
+#include <QtEndian>
+
+#include "ggv_bin.h"
+
+#define MYNAME "ggv_bin"
+
+/***************************************************************************
+ * local helper functions *
+ ***************************************************************************/
+
+void
+GgvBinFormat::ggv_bin_read_bytes(QDataStream& stream, QByteArray& buf, int len, const char* descr)
+{
+ if (len < 0) {
+ fatal(MYNAME ": Read error, negative len (%s)\n", descr ? descr : "");
+ }
+ buf.resize(len);
+ if (stream.readRawData(buf.data(), len) != len || stream.status() != QDataStream::Ok) {
+ fatal(MYNAME ": Read error (%s)\n", descr ? descr : "");
+ }
+}
+
+quint16
+GgvBinFormat::ggv_bin_read16(QDataStream& stream, const char* descr)
+{
+ quint16 res;
+ stream >> res;
+ if (stream.status() != QDataStream::Ok) {
+ fatal(MYNAME ": Read error (%s)\n", descr ? descr : "");
+ }
+ if (global_opts.debug_level > 1) {
+ qDebug("ovl: %-15s %5u (0x%04x)", descr, res, res);
+ }
+ return res;
+}
+
+quint32
+GgvBinFormat::ggv_bin_read32(QDataStream& stream, const char* descr)
+{
+ quint32 res;
+ stream >> res;
+ if (stream.status() != QDataStream::Ok) {
+ fatal(MYNAME ": Read error (%s)\n", descr ? descr : "");
+ }
+ if (global_opts.debug_level > 1) {
+ if ((res & 0xFFFF0000) == 0) {
+ qDebug("ovl: %-15s %5u (0x%08x)", descr, res, res);
+ } else {
+ qDebug("ovl: %-15s (0x%08x)", descr, res);
+ }
+ }
+ return res;
+}
+
+void
+GgvBinFormat::ggv_bin_read_text16(QDataStream& stream, QByteArray& buf, const char* descr)
+{
+ quint16 len = ggv_bin_read16(stream, descr);
+ ggv_bin_read_bytes(stream, buf, len, descr);
+ buf.append('\0');
+ if (global_opts.debug_level > 1) {
+ qDebug() << "ovl: text =" << QString::fromLatin1(buf.constData()).simplified();
+ }
+}
+
+void
+GgvBinFormat::ggv_bin_read_text32(QDataStream& stream, QByteArray& buf, const char* descr)
+{
+ quint32 len = ggv_bin_read32(stream, descr);
+ // The following check prevents passing an unsigned int with a
+ // value greater than INT32_MAX to a signed int parameter in
+ // ggv_bin_read_bytes later on. If this happens, the file is
+ // almost certainly corrupted.
+ if (len > INT32_MAX) {
+ fatal(MYNAME ": Read error, max len exceeded (%s)\n", descr ? descr : "");
+ }
+ ggv_bin_read_bytes(stream, buf, len, descr);
+ buf.append('\0');
+ if (global_opts.debug_level > 1) {
+ qDebug() << "ovl: text =" << QString::fromLatin1(buf.constData()).simplified();
+ }
+}
+
+double
+GgvBinFormat::ggv_bin_read_double(QDataStream& stream, const char* descr)
+{
+ double res;
+ stream >> res;
+ if (stream.status() != QDataStream::Ok) {
+ fatal(MYNAME ": Read error (%s)\n", descr ? descr : "");
+ }
+ return res;
+}
+
+/***************************************************************************
+ * OVL Version 2.0 *
+ ***************************************************************************/
+
+void
+GgvBinFormat::ggv_bin_read_v2(QDataStream& stream)
+{
+ QByteArray buf;
+ QString track_name;
+ QString waypt_name;
+ route_head* ggv_bin_track;
+ Waypoint* wpt;
+ double lon, lat;
+ quint16 line_points;
+
+ // header length is usually either 0x90 or 0x00
+ quint16 header_len = ggv_bin_read16(stream, "map name len");
+ if (header_len > 0) {
+ ggv_bin_read_bytes(stream, buf, header_len, "map name");
+ buf.remove(0,4);
+ buf.append('\0');
+ if (global_opts.debug_level > 1) {
+ qDebug() << "ovl: name =" << buf.constData();
+ }
+ }
+
+ while (!stream.atEnd()) {
+ track_name.clear();
+
+ if (global_opts.debug_level > 1) {
+ qDebug("------------------------------------ 0x%llx", stream.device()->pos());
+ }
+
+ auto entry_pos = stream.device()->pos();
+ quint16 entry_type = ggv_bin_read16(stream, "entry type");
+ ggv_bin_read16(stream, "entry group");
+ ggv_bin_read16(stream, "entry zoom");
+ quint16 entry_subtype = ggv_bin_read16(stream, "entry subtype");
+
+ if (entry_subtype != 1) {
+ ggv_bin_read_text32(stream, buf, "text len");
+ track_name = QString::fromLatin1(buf.constData()).simplified();
+ }
+
+ switch (entry_type) {
+ case 0x02:
+ // text
+ ggv_bin_read16(stream, "text color");
+ ggv_bin_read16(stream, "text size");
+ ggv_bin_read16(stream, "text trans");
+ ggv_bin_read16(stream, "text font");
+ ggv_bin_read16(stream, "text angle");
+ lon = ggv_bin_read_double(stream, "text lon");
+ lat = ggv_bin_read_double(stream, "text lat");
+ ggv_bin_read_text16(stream, buf, "text label");
+ waypt_name = QString::fromLatin1(buf.constData()).simplified();
+ wpt = new Waypoint;
+ wpt->longitude = lon;
+ wpt->latitude = lat;
+ wpt->description = waypt_name;
+ waypt_add(wpt);
+ break;
+ case 0x03:
+ // line
+ case 0x04:
+ // area
+ ggv_bin_read16(stream, "line color");
+ ggv_bin_read16(stream, "line width");
+ ggv_bin_read16(stream, "line type");
+ line_points = ggv_bin_read16(stream, "line points");
+ ggv_bin_track = new route_head;
+ track_add_head(ggv_bin_track);
+ if (! track_name.isEmpty()) {
+ ggv_bin_track->rte_name = track_name;
+ }
+
+ for (int i = 1; i <= line_points; i++) {
+ lon = ggv_bin_read_double(stream, "line lon");
+ lat = ggv_bin_read_double(stream, "line lat");
+ wpt = new Waypoint;
+ wpt->longitude = lon;
+ wpt->latitude = lat;
+ track_add_wpt(ggv_bin_track, wpt);
+ }
+ break;
+ case 0x05:
+ // rectangle
+ case 0x06:
+ // circle
+ case 0x07:
+ // triangle
+ ggv_bin_read16(stream, "geom color");
+ ggv_bin_read16(stream, "geom prop1");
+ ggv_bin_read16(stream, "geom prop2");
+ ggv_bin_read16(stream, "geom angle");
+ ggv_bin_read16(stream, "geom stroke");
+ ggv_bin_read16(stream, "geom area");
+ ggv_bin_read_double(stream, "geom lon");
+ ggv_bin_read_double(stream, "geom lat");
+ break;
+ case 0x09:
+ ggv_bin_read16(stream, "bmp color");
+ ggv_bin_read16(stream, "bmp prop1");
+ ggv_bin_read16(stream, "bmp prop2");
+ ggv_bin_read16(stream, "bmp prop3");
+ ggv_bin_read_double(stream, "bmp lon");
+ ggv_bin_read_double(stream, "bmp lat");
+ ggv_bin_read_text32(stream, buf, "bmp data");
+ break;
+ default:
+ fatal(MYNAME ": Unknown entry type (0x%hx, pos=0x%llx) \n", entry_type, entry_pos);
+ }
+ }
+}
+
+/***************************************************************************
+ * OVL Version 3.0 and 4.0 *
+ ***************************************************************************/
+
+void
+GgvBinFormat::ggv_bin_read_v34_header(QDataStream& stream, quint32& number_labels, quint32& number_records)
+{
+ QByteArray buf;
+
+ ggv_bin_read_bytes(stream, buf, 8, "unknown");
+ number_labels = ggv_bin_read32(stream, "num labels");
+ number_records = ggv_bin_read32(stream, "num records");
+ ggv_bin_read_text16(stream, buf, "text label");
+ ggv_bin_read16(stream, "unknown");
+ ggv_bin_read16(stream, "unknown");
+ // 8 bytes ending with 1E 00, contains len of header block
+ ggv_bin_read16(stream, "unknown");
+ quint16 header_len = ggv_bin_read16(stream, "header len");
+ ggv_bin_read16(stream, "unknown");
+ ggv_bin_read16(stream, "unknown");
+ if (header_len > 0) {
+ ggv_bin_read_bytes(stream, buf, header_len, "map name");
+ buf.remove(0,4);
+ buf.append('\0');
+ if (global_opts.debug_level > 1) {
+ qDebug() << "ovl: name =" << buf.constData();
+ }
+ }
+}
+
+void
+GgvBinFormat::ggv_bin_read_v34_label(QDataStream& stream)
+{
+ QByteArray buf;
+
+ if (global_opts.debug_level > 1) {
+ qDebug("------------------------------------ 0x%llx", stream.device()->pos());
+ }
+ ggv_bin_read_bytes(stream, buf, 0x08, "label header");
+ ggv_bin_read_bytes(stream, buf, 0x14, "label number");
+ ggv_bin_read_text16(stream, buf, "label text");
+ ggv_bin_read16(stream, "label flag1");
+ ggv_bin_read16(stream, "label flag2");
+}
+
+QString
+GgvBinFormat::ggv_bin_read_v34_common(QDataStream& stream)
+{
+ QByteArray buf;
+
+ ggv_bin_read16(stream, "entry group");
+ ggv_bin_read16(stream, "entry prop2");
+ ggv_bin_read16(stream, "entry prop3");
+ ggv_bin_read16(stream, "entry prop4");
+ ggv_bin_read16(stream, "entry prop5");
+ ggv_bin_read16(stream, "entry prop6");
+ ggv_bin_read16(stream, "entry prop7");
+ ggv_bin_read16(stream, "entry prop8");
+ ggv_bin_read16(stream, "entry zoom");
+ ggv_bin_read16(stream, "entry prop10");
+ ggv_bin_read_text16(stream, buf, "entry txt");
+ QString res = QString::fromLatin1(buf.constData()).simplified();
+ quint16 type1 = ggv_bin_read16(stream, "entry type1");
+ if (type1 != 1) {
+ ggv_bin_read_text32(stream, buf, "entry object");
+ }
+ quint16 type2 = ggv_bin_read16(stream, "entry type2");
+ if (type2 != 1) {
+ ggv_bin_read_text32(stream, buf, "entry object");
+ }
+ return res;
+}
+
+void
+GgvBinFormat::ggv_bin_read_v34_record(QDataStream& stream)
+{
+ QByteArray buf;
+ Waypoint* wpt;
+ route_head* ggv_bin_track;
+ quint32 bmp_len;
+ quint16 line_points;
+ double lon, lat;
+
+ if (global_opts.debug_level > 1) {
+ qDebug("------------------------------------ 0x%llx", stream.device()->pos());
+ }
+
+ quint16 entry_type = ggv_bin_read16(stream, "entry type");
+ QString label = ggv_bin_read_v34_common(stream);
+
+ switch (entry_type) {
+ case 0x02:
+ // text
+ ggv_bin_read16(stream, "text prop1");
+ ggv_bin_read32(stream, "text prop2");
+ ggv_bin_read16(stream, "text prop3");
+ ggv_bin_read32(stream, "text prop4");
+ ggv_bin_read16(stream, "text ltype");
+ ggv_bin_read16(stream, "text angle");
+ ggv_bin_read16(stream, "text size");
+ ggv_bin_read16(stream, "text area");
+ lon = ggv_bin_read_double(stream, "text lon");
+ lat = ggv_bin_read_double(stream, "text lat");
+ ggv_bin_read_double(stream, "text unk");
+ ggv_bin_read_text16(stream, buf, "text label");
+ wpt = new Waypoint;
+ wpt->longitude = lon;
+ wpt->latitude = lat;
+ wpt->description = QString::fromLatin1(buf.constData()).simplified();
+ waypt_add(wpt);
+ break;
+ case 0x03:
+ case 0x04:
+ // area
+ case 0x17:
+ // line
+ ggv_bin_track = new route_head;
+ track_add_head(ggv_bin_track);
+
+ if (! label.isEmpty()) {
+ ggv_bin_track->rte_name = label;
+ }
+
+ ggv_bin_read16(stream, "line prop1");
+ ggv_bin_read32(stream, "line prop2");
+ ggv_bin_read16(stream, "line prop3");
+ ggv_bin_read32(stream, "line color");
+ ggv_bin_read16(stream, "line size");
+ ggv_bin_read16(stream, "line stroke");
+ line_points = ggv_bin_read16(stream, "line points");
+ if (entry_type == 0x04) {
+ // found in example.ovl generated by Geogrid-Viewer 1.0
+ ggv_bin_read16(stream, "line pad");
+ }
+
+ for (int i=1; i <= line_points; i++) {
+ lon = ggv_bin_read_double(stream, "line lon");
+ lat = ggv_bin_read_double(stream, "line lat");
+ ggv_bin_read_double(stream, "line unk");
+ wpt = new Waypoint;
+ wpt->longitude = lon;
+ wpt->latitude = lat;
+ track_add_wpt(ggv_bin_track, wpt);
+ }
+ break;
+ case 0x05:
+ case 0x06:
+ case 0x07:
+ // circle
+ ggv_bin_read16(stream, "circle prop1");
+ ggv_bin_read32(stream, "circle prop2");
+ ggv_bin_read16(stream, "circle prop3");
+ ggv_bin_read32(stream, "circle color");
+ ggv_bin_read32(stream, "circle prop5");
+ ggv_bin_read32(stream, "circle prop6");
+ ggv_bin_read16(stream, "circle ltype");
+ ggv_bin_read16(stream, "circle angle");
+ ggv_bin_read16(stream, "circle size");
+ ggv_bin_read16(stream, "circle area");
+ ggv_bin_read_double(stream, "circle lon");
+ ggv_bin_read_double(stream, "circle lat");
+ ggv_bin_read_double(stream, "circle unk");
+ break;
+ case 0x09:
+ // bmp
+ ggv_bin_read16(stream, "bmp prop1");
+ ggv_bin_read32(stream, "bmp prop2");
+ ggv_bin_read16(stream, "bmp prop3");
+ ggv_bin_read32(stream, "bmp prop4");
+ ggv_bin_read32(stream, "bmp prop5");
+ ggv_bin_read32(stream, "bmp prop6");
+ ggv_bin_read_double(stream, "bmp lon");
+ ggv_bin_read_double(stream, "bmp lat");
+ ggv_bin_read_double(stream, "bmp unk");
+ bmp_len = ggv_bin_read32(stream, "bmp len");
+ // The following check prevents passing an unsigned int with a
+ // value greater than INT32_MAX to a signed int parameter in
+ // ggv_bin_read_bytes later on. If this happens, the file is
+ // almost certainly corrupted.
+ if (bmp_len > INT32_MAX) {
+ fatal(MYNAME ": Read error, max bmp_len exceeded\n");
+ }
+ ggv_bin_read16(stream, "bmp prop");
+ ggv_bin_read_bytes(stream, buf, bmp_len, "bmp data");
+ break;
+ default:
+ fatal(MYNAME ": Unsupported type: %x\n", entry_type);
+ }
+}
+
+void
+GgvBinFormat::ggv_bin_read_v34(QDataStream& stream)
+{
+ QByteArray buf;
+ quint32 label_count;
+ quint32 record_count;
+
+ while (!stream.atEnd()) {
+ ggv_bin_read_v34_header(stream, label_count, record_count);
+
+ if (label_count && !stream.atEnd()) {
+ if (global_opts.debug_level > 1) {
+ qDebug("-----labels------------------------- 0x%llx", stream.device()->pos());
+ }
+ for (unsigned int i = 0; i < label_count; i++) {
+ ggv_bin_read_v34_label(stream);
+ }
+ }
+
+ if (record_count && !stream.atEnd()) {
+ if (global_opts.debug_level > 1) {
+ qDebug("-----records------------------------ 0x%llx", stream.device()->pos());
+ }
+ for (unsigned int i = 0; i < record_count; i++) {
+ ggv_bin_read_v34_record(stream);
+ }
+ }
+
+ if (!stream.atEnd()) {
+ if (global_opts.debug_level > 1) {
+ qDebug("------------------------------------ 0x%llx", stream.device()->pos());
+ }
+ // we just skip over the next magic bytes without checking they
+ // contain the correct string. This is consistent with what I
+ // believe GGV does
+ ggv_bin_read_bytes(stream, buf, 23, "magicbytes");
+ if (global_opts.debug_level > 1) {
+ qDebug() << "ovl: header = " << buf.constData();
+ }
+ }
+ }
+
+ if (global_opts.debug_level > 1) {
+ qDebug("fpos: 0x%llx", stream.device()->pos());
+ qDebug("size: 0x%llx", stream.device()->size());
+ }
+}
+
+/***************************************************************************
+ * entry points called by gpsbabel main process *
+ ***************************************************************************/
+
+void
+GgvBinFormat::read()
+{
+ QFile file(read_fname);
+ if (!file.open(QIODevice::ReadOnly)) {
+ fatal(MYNAME ": Error opening file %s\n", qPrintable(read_fname));
+ }
+
+ QDataStream stream(&file);
+ stream.setFloatingPointPrecision(QDataStream::DoublePrecision);
+ stream.setByteOrder(QDataStream::LittleEndian);
+
+ QByteArray buf;
+ ggv_bin_read_bytes(stream, buf, 0x17, "magic");
+ buf.append('\0');
+ if (global_opts.debug_level > 1) {
+ qDebug() << "ovl: header =" << buf.constData();
+ }
+
+ if (buf.startsWith("DOMGVCRD Ovlfile V2.0")) {
+ ggv_bin_read_v2(stream);
+ } else if (buf.startsWith("DOMGVCRD Ovlfile V3.0")) {
+ ggv_bin_read_v34(stream);
+ } else if (buf.startsWith("DOMGVCRD Ovlfile V4.0")) {
+ ggv_bin_read_v34(stream);
+ } else {
+ fatal(MYNAME ": Unsupported file format\n");
+ }
+
+ file.close();
+}
+
+void
+GgvBinFormat::rd_init(const QString& fname)
+{
+ read_fname = fname;
+}
+
+void
+GgvBinFormat::rd_deinit()
+{
+ read_fname.clear();
+}
+
--- /dev/null
+/*
+
+ Handle Geogrid-Viewer binary overlay file format (.ovl)
+
+ Copyright (C) 2016-2020 Ralf Horstmann <ralf@ackstorm.de>
+ Copyright (C) 2016-2020 Robert Lipe, robertlipe+source@gpsbabel.org
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+#ifndef GGV_BIN_H_INCLUDED_
+#define GGV_BIN_H_INCLUDED_
+
+#include "defs.h"
+#include "format.h"
+
+
+class GgvBinFormat : public Format
+{
+public:
+ ff_type get_type() const override
+ {
+ return ff_type_file;
+ }
+
+ QVector<ff_cap> get_cap() const override
+ {
+ return {
+ ff_cap_none, // waypoints
+ ff_cap_read, // tracks
+ ff_cap_none // routes
+ };
+ }
+
+ QString get_encode() const override
+ {
+ return CET_CHARSET_ASCII;
+ }
+
+ int get_fixed_encode() const override
+ {
+ return 0;
+ }
+
+ void rd_init(const QString& fname) override;
+ void read() override;
+ void rd_deinit() override;
+
+private:
+ static void ggv_bin_read_bytes(QDataStream& stream, QByteArray& buf, int len, const char* descr = nullptr);
+ static quint16 ggv_bin_read16(QDataStream& stream, const char* descr = nullptr);
+ static quint32 ggv_bin_read32(QDataStream& stream, const char* descr = nullptr);
+ static void ggv_bin_read_text16(QDataStream& stream, QByteArray& buf, const char* descr = nullptr);
+ static void ggv_bin_read_text32(QDataStream& stream, QByteArray& buf, const char* descr = nullptr);
+ static double ggv_bin_read_double(QDataStream& stream, const char* descr = nullptr);
+ static void ggv_bin_read_v2(QDataStream& stream);
+ static void ggv_bin_read_v34_header(QDataStream& stream, quint32& number_labels, quint32& number_records);
+ static void ggv_bin_read_v34_label(QDataStream& stream);
+ static QString ggv_bin_read_v34_common(QDataStream& stream);
+ static void ggv_bin_read_v34_record(QDataStream& stream);
+ static void ggv_bin_read_v34(QDataStream& stream);
+
+ QString read_fname;
+
+};
+
+#endif
--- /dev/null
+/*
+
+ Support for "GeoGrid Viewer ascii overlay files".
+
+ Copyright (C) 2008 Olaf Klein (o.b.klein@gpsbabel.org).
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ */
+
+#include <cmath> // for sin, cos, acos
+
+#include <QString> // for QString
+#include <QVector> // for QVector
+#include <QtGlobal> // for foreach
+
+#include "defs.h"
+#include "gbfile.h" // for gbfprintf, gbfclose, gbfopen, gbfile
+#include "grtcirc.h" // for RAD, gcdist, DEG
+#include "inifile.h" // for inifile_readstr, inifile_readint_def, inifile_done, inifile_init, inifile_readint, inifile_t
+
+
+#define MYNAME "ggv_ovl"
+
+static
+QVector<arglist_t> ggv_ovl_args = {
+};
+
+enum OVL_SYMBOL_TYP {
+ OVL_SYMBOL_BITMAP = 1,
+ OVL_SYMBOL_TEXT,
+ OVL_SYMBOL_LINE,
+ OVL_SYMBOL_POLYGON,
+ OVL_SYMBOL_RECTANGLE,
+ OVL_SYMBOL_CIRCLE,
+ OVL_SYMBOL_TRIANGLE
+};
+
+enum OVL_COLOR_TYP {
+ OVL_COLOR_RED = 1, /* = 1 */
+ OVL_COLOR_LIME, /* = 2 */
+ OVL_COLOR_BLUE, /* = 3 */
+ OVL_COLOR_YELLOW, /* = 4 */
+ OVL_COLOR_BLACK, /* = 5 */
+ OVL_COLOR_WHITE, /* = 6 */
+ OVL_COLOR_7, /* = 7 (draws only a simple line) */
+ OVL_COLOR_FUCHSIA, /* = 8 */
+ OVL_COLOR_AQUA, /* = 9 */
+};
+
+/* some hints:
+ # "col": color
+ # "group": 1 means NO GROUP
+ # "size": size in pixels PLUS 100
+ # "with":
+ # "zoom":
+ # "art": line-style
+ */
+static inifile_t* inifile;
+static gbfile* fout;
+
+static int symbol_ct; /* Number of symbols written */
+static int group_ct; /* Group number during write */
+static int track_ct, route_ct;
+static bounds all_bounds;
+static OVL_COLOR_TYP color;
+
+/*******************************************************************************
+* %%% global callbacks called by gpsbabel main process %%% *
+*******************************************************************************/
+
+static void
+ggv_ovl_rd_init(const QString& fname)
+{
+ inifile = inifile_init(fname, MYNAME);
+
+ route_ct = 0;
+ track_ct = 0;
+}
+
+static void
+ggv_ovl_rd_deinit()
+{
+ inifile_done(inifile);
+}
+
+static void
+ggv_ovl_read()
+{
+ int symbols = inifile_readint_def(inifile, "Overlay", "Symbols", -1);
+
+ for (int i = 1; i <= symbols; ++i) {
+
+ QString symbol = QString("Symbol %1").arg(i);
+
+ OVL_SYMBOL_TYP type = (OVL_SYMBOL_TYP) inifile_readint_def(inifile, symbol, "Typ", 0);
+ int points = inifile_readint_def(inifile, symbol, "Punkte", -1);
+
+ QString lat;
+ QString lon;
+ switch (type) {
+
+ Waypoint* wpt;
+ int group;
+
+ case OVL_SYMBOL_LINE:
+ case OVL_SYMBOL_POLYGON:
+
+ if (!inifile_readint(inifile, symbol, "Group", &group)) {
+ group = -1;
+ }
+
+ if (points > 0) {
+ route_head* trk;
+
+ auto* rte = trk = new route_head;
+ if (group > 1) {
+ route_add_head(rte);
+ route_ct++;
+ rte->rte_name = QString("Route %1").arg(route_ct);
+ } else {
+ track_add_head(trk);
+ track_ct++;
+ trk->rte_name = QString("Track %1").arg(track_ct);
+ }
+
+ for (int j = 0; j < points; ++j) {
+
+ wpt = new Waypoint;
+
+ lat = inifile_readstr(inifile, symbol, QString("YKoord%1").arg(j));
+ if (lat.isNull()) {
+ delete wpt;
+ continue;
+ }
+ wpt->latitude = lat.toDouble();
+
+ lon = inifile_readstr(inifile, symbol, QString("XKoord%1").arg(j));
+ if (lon.isNull()) {
+ delete wpt;
+ continue;
+ }
+ wpt->longitude = lon.toDouble();
+
+ if (group > 1) {
+ route_add_wpt(rte, wpt);
+ } else {
+ track_add_wpt(trk, wpt);
+ }
+ }
+ }
+ break;
+
+ case OVL_SYMBOL_CIRCLE:
+ case OVL_SYMBOL_TRIANGLE:
+
+ wpt = new Waypoint;
+ wpt->shortname = symbol;
+
+ lat = inifile_readstr(inifile, symbol, "YKoord");
+ if (lat.isNull()) {
+ delete wpt;
+ continue;
+ }
+ wpt->latitude = lat.toDouble();
+ lon = inifile_readstr(inifile, symbol, "XKoord");
+ if (lon.isNull()) {
+ delete wpt;
+ continue;
+ }
+ wpt->longitude = lon.toDouble();
+
+ waypt_add(wpt);
+ break;
+
+ case OVL_SYMBOL_BITMAP:
+ case OVL_SYMBOL_TEXT:
+ case OVL_SYMBOL_RECTANGLE:
+ break;
+ }
+ }
+}
+
+/**************************************************************************/
+
+/* prototypes used in main functions */
+
+static void waypt_disp_cb(const Waypoint* wpt);
+static void track_disp_cb(const route_head* trk);
+static void route_disp_cb(const route_head* rte);
+static void write_bounds();
+static void draw_symbol_basics(OVL_SYMBOL_TYP typ, int art, OVL_COLOR_TYP color, const Waypoint* wpt);
+static int get_direction(const Waypoint* A, const Waypoint* B);
+// static void draw_symbol_text(const char *text, const waypoint *reference);
+
+/* -----------------------------------------------------------------------*/
+
+static void
+ggv_ovl_wr_init(const QString& fname)
+{
+ fout = gbfopen(fname, "w", MYNAME);
+
+ symbol_ct = 0;
+}
+
+static void
+ggv_ovl_wr_deinit()
+{
+ gbfclose(fout);
+}
+
+static void
+ggv_ovl_write()
+{
+ group_ct = 1; /* tracks are not grouped */
+ color = OVL_COLOR_FUCHSIA;
+ track_disp_all(track_disp_cb, nullptr, nullptr);
+
+ group_ct++;
+ color = OVL_COLOR_AQUA;
+ route_disp_all(route_disp_cb, nullptr, nullptr);
+
+ group_ct++;
+ color = OVL_COLOR_LIME;
+ waypt_disp_all(waypt_disp_cb);
+
+ gbfprintf(fout, "[Overlay]\n");
+ gbfprintf(fout, "Symbols=%d\n", symbol_ct);
+ gbfprintf(fout, "[MapLage]\n");
+ gbfprintf(fout, "MapName=Bundesrepublik 1:1 Mio\n");
+ gbfprintf(fout, "DimmFc=100\n");
+ gbfprintf(fout, "ZoomFc=100\n");
+ write_bounds();
+ gbfprintf(fout, "RefOn=0\n"); /* no reference point */
+}
+
+/**************************************************************************/
+
+static void
+waypt_disp_cb(const Waypoint* wpt)
+{
+ draw_symbol_basics(OVL_SYMBOL_CIRCLE, 1, color, wpt);
+ gbfprintf(fout, "Width=20\n");
+ gbfprintf(fout, "Height=20\n");
+ gbfprintf(fout, "Dir=100\n");
+ gbfprintf(fout, "Zoom=1\n");
+ gbfprintf(fout, "Size=102\n");
+ gbfprintf(fout, "Area=2\n");
+// draw_symbol_text(wpt->shortname, wpt);
+}
+
+/* -----------------------------------------------------------------------*/
+
+static void
+track_disp_cb(const route_head* trk)
+{
+ int waypt_ct = trk->rte_waypt_ct();
+
+ if (waypt_ct <= 0) {
+ return;
+ }
+
+ draw_symbol_basics(OVL_SYMBOL_LINE, 1, color, nullptr);
+
+ gbfprintf(fout, "Zoom=1\n");
+ gbfprintf(fout, "Size=105\n");
+ gbfprintf(fout, "Punkte=%d\n", waypt_ct);
+
+ int i = 0;
+
+ foreach (const Waypoint* wpt, trk->waypoint_list) {
+
+ gbfprintf(fout, "XKoord%d=%0.8f\n", i, wpt->longitude);
+ gbfprintf(fout, "YKoord%d=%0.8f\n", i, wpt->latitude);
+
+ i++;
+ }
+}
+
+/* -----------------------------------------------------------------------*/
+
+static void
+route_disp_cb(const route_head* rte)
+{
+ int waypt_ct = rte->rte_waypt_ct();
+
+ if (waypt_ct <= 0) {
+ return;
+ }
+
+ track_disp_cb(rte); /* draw a line as tracks */
+
+ color = OVL_COLOR_RED;
+
+ int i = 0;
+ const Waypoint* prev = nullptr;
+
+ foreach (const Waypoint* wpt, rte->waypoint_list) {
+
+ if (prev != nullptr) {
+ draw_symbol_basics(OVL_SYMBOL_TRIANGLE, 1, (OVL_COLOR_TYP)9 /* color */, prev);
+
+ gbfprintf(fout, "Width=12\n");
+ gbfprintf(fout, "Height=8\n");
+ gbfprintf(fout, "Dir=%d\n", 100 + get_direction(prev, wpt));
+ gbfprintf(fout, "Zoom=1\n");
+ gbfprintf(fout, "Size=101\n");
+ gbfprintf(fout, "Area=2\n");
+ }
+
+ i++;
+ prev = wpt;
+ }
+}
+
+/* -----------------------------------------------------------------------*/
+
+static void
+waypt_bound_calc(const Waypoint* waypointp)
+{
+ waypt_add_to_bounds(&all_bounds, waypointp);
+}
+
+static void
+write_bounds()
+{
+ waypt_init_bounds(&all_bounds);
+
+ waypt_disp_all(waypt_bound_calc);
+ route_disp_all(nullptr, nullptr, waypt_bound_calc);
+ track_disp_all(nullptr, nullptr, waypt_bound_calc);
+
+ if (waypt_bounds_valid(&all_bounds)) {
+
+ double cx = all_bounds.min_lat + ((all_bounds.max_lat - all_bounds.min_lat) / 2);
+ double cy = all_bounds.min_lon + ((all_bounds.max_lon - all_bounds.min_lon) / 2);
+
+ gbfprintf(fout, "CenterLat=%0.8f\n", cx);
+ gbfprintf(fout, "CenterLong=%0.8f\n", cy);
+ } else {
+ gbfprintf(fout, "CenterLong=10.52374295\n");
+ gbfprintf(fout, "CenterLat=52.26474445\n");
+ }
+}
+
+static void
+draw_symbol_basics(const OVL_SYMBOL_TYP typ, const int art,
+ const OVL_COLOR_TYP point_color, const Waypoint* wpt)
+{
+ symbol_ct++;
+
+ gbfprintf(fout, "[Symbol %d]\n", symbol_ct);
+ gbfprintf(fout, "Typ=%d\n", typ);
+ gbfprintf(fout, "Group=%d\n", group_ct);
+ gbfprintf(fout, "Col=%d\n", point_color);
+ if (art >= 0) {
+ gbfprintf(fout, "Art=%d\n", art);
+ }
+ if (wpt) {
+ gbfprintf(fout, "XKoord=%.8f\n", wpt->longitude);
+ gbfprintf(fout, "YKoord=%.8f\n", wpt->latitude);
+ }
+}
+
+/* the following code comes from first overlay module */
+
+static int
+get_direction(const Waypoint* A, const Waypoint* B)
+{
+ double lata = RAD(A->latitude);
+ double lona = RAD(A->longitude);
+ double latb = RAD(B->latitude);
+ double lonb = RAD(B->longitude);
+
+ double dist = gcdist(lata, lona, latb, lonb);
+ double dir = acos((sin(latb) - sin(lata) * cos(dist)) / (cos(lata) * sin(dist)));
+ if (lonb < lona) {
+ dir = -dir;
+ }
+ int res = (int) DEG(dir);
+ res = 360 - (res + 270);
+ if (res < 0) {
+ res += 360;
+ } else if (res > 360) {
+ res -= 360.0;
+ }
+
+ return res;
+}
+
+#if 0
+static void
+draw_symbol_text(const char* text, const Waypoint* reference)
+{
+ Waypoint wpt;
+
+ if ((reference == NULL) || (text == NULL)) {
+ return;
+ }
+ if (*text == '\0') {
+ return;
+ }
+
+ wpt = *reference;
+
+ wpt.latitude = wpt.latitude + 0.015;
+ wpt.longitude = wpt.longitude + 0.015;
+
+ draw_symbol_basics(OVL_SYMBOL_TEXT, -1, OVL_COLOR_BLACK, &wpt);
+
+ gbfprintf(fout, "Area=1\n");
+ gbfprintf(fout, "Zoom=1\n");
+ gbfprintf(fout, "Size=120\n");
+ gbfprintf(fout, "Font=3\n");
+ gbfprintf(fout, "Dir=100\n");
+ gbfprintf(fout, "Text=%s\n", text);
+}
+#endif
+
+/**************************************************************************/
+
+ff_vecs_t ggv_ovl_vecs = {
+ ff_type_file,
+ FF_CAP_RW_ALL,
+ ggv_ovl_rd_init,
+ ggv_ovl_wr_init,
+ ggv_ovl_rd_deinit,
+ ggv_ovl_wr_deinit,
+ ggv_ovl_read,
+ ggv_ovl_write,
+ nullptr,
+ &ggv_ovl_args,
+ CET_CHARSET_MS_ANSI, 0
+ , NULL_POS_OPS
+};
+
+/**************************************************************************/
+++ /dev/null
-/*
-
- Handle Geogrid-Viewer binary overlay file format (.ovl)
-
- Copyright (C) 2016-2020 Ralf Horstmann <ralf@ackstorm.de>
- Copyright (C) 2016-2020 Robert Lipe, robertlipe+source@gpsbabel.org
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-*/
-
-#include <QByteArray>
-#include <QDataStream>
-#include <QDebug>
-#include <QFile>
-#include <QtEndian>
-
-#include "ggv_bin.h"
-
-#define MYNAME "ggv_bin"
-
-/***************************************************************************
- * local helper functions *
- ***************************************************************************/
-
-void
-GgvBinFormat::ggv_bin_read_bytes(QDataStream& stream, QByteArray& buf, int len, const char* descr)
-{
- if (len < 0) {
- fatal(MYNAME ": Read error, negative len (%s)\n", descr ? descr : "");
- }
- buf.resize(len);
- if (stream.readRawData(buf.data(), len) != len || stream.status() != QDataStream::Ok) {
- fatal(MYNAME ": Read error (%s)\n", descr ? descr : "");
- }
-}
-
-quint16
-GgvBinFormat::ggv_bin_read16(QDataStream& stream, const char* descr)
-{
- quint16 res;
- stream >> res;
- if (stream.status() != QDataStream::Ok) {
- fatal(MYNAME ": Read error (%s)\n", descr ? descr : "");
- }
- if (global_opts.debug_level > 1) {
- qDebug("ovl: %-15s %5u (0x%04x)", descr, res, res);
- }
- return res;
-}
-
-quint32
-GgvBinFormat::ggv_bin_read32(QDataStream& stream, const char* descr)
-{
- quint32 res;
- stream >> res;
- if (stream.status() != QDataStream::Ok) {
- fatal(MYNAME ": Read error (%s)\n", descr ? descr : "");
- }
- if (global_opts.debug_level > 1) {
- if ((res & 0xFFFF0000) == 0) {
- qDebug("ovl: %-15s %5u (0x%08x)", descr, res, res);
- } else {
- qDebug("ovl: %-15s (0x%08x)", descr, res);
- }
- }
- return res;
-}
-
-void
-GgvBinFormat::ggv_bin_read_text16(QDataStream& stream, QByteArray& buf, const char* descr)
-{
- quint16 len = ggv_bin_read16(stream, descr);
- ggv_bin_read_bytes(stream, buf, len, descr);
- buf.append('\0');
- if (global_opts.debug_level > 1) {
- qDebug() << "ovl: text =" << QString::fromLatin1(buf.constData()).simplified();
- }
-}
-
-void
-GgvBinFormat::ggv_bin_read_text32(QDataStream& stream, QByteArray& buf, const char* descr)
-{
- quint32 len = ggv_bin_read32(stream, descr);
- // The following check prevents passing an unsigned int with a
- // value greater than INT32_MAX to a signed int parameter in
- // ggv_bin_read_bytes later on. If this happens, the file is
- // almost certainly corrupted.
- if (len > INT32_MAX) {
- fatal(MYNAME ": Read error, max len exceeded (%s)\n", descr ? descr : "");
- }
- ggv_bin_read_bytes(stream, buf, len, descr);
- buf.append('\0');
- if (global_opts.debug_level > 1) {
- qDebug() << "ovl: text =" << QString::fromLatin1(buf.constData()).simplified();
- }
-}
-
-double
-GgvBinFormat::ggv_bin_read_double(QDataStream& stream, const char* descr)
-{
- double res;
- stream >> res;
- if (stream.status() != QDataStream::Ok) {
- fatal(MYNAME ": Read error (%s)\n", descr ? descr : "");
- }
- return res;
-}
-
-/***************************************************************************
- * OVL Version 2.0 *
- ***************************************************************************/
-
-void
-GgvBinFormat::ggv_bin_read_v2(QDataStream& stream)
-{
- QByteArray buf;
- QString track_name;
- QString waypt_name;
- route_head* ggv_bin_track;
- Waypoint* wpt;
- double lon, lat;
- quint16 line_points;
-
- // header length is usually either 0x90 or 0x00
- quint16 header_len = ggv_bin_read16(stream, "map name len");
- if (header_len > 0) {
- ggv_bin_read_bytes(stream, buf, header_len, "map name");
- buf.remove(0,4);
- buf.append('\0');
- if (global_opts.debug_level > 1) {
- qDebug() << "ovl: name =" << buf.constData();
- }
- }
-
- while (!stream.atEnd()) {
- track_name.clear();
-
- if (global_opts.debug_level > 1) {
- qDebug("------------------------------------ 0x%llx", stream.device()->pos());
- }
-
- auto entry_pos = stream.device()->pos();
- quint16 entry_type = ggv_bin_read16(stream, "entry type");
- ggv_bin_read16(stream, "entry group");
- ggv_bin_read16(stream, "entry zoom");
- quint16 entry_subtype = ggv_bin_read16(stream, "entry subtype");
-
- if (entry_subtype != 1) {
- ggv_bin_read_text32(stream, buf, "text len");
- track_name = QString::fromLatin1(buf.constData()).simplified();
- }
-
- switch (entry_type) {
- case 0x02:
- // text
- ggv_bin_read16(stream, "text color");
- ggv_bin_read16(stream, "text size");
- ggv_bin_read16(stream, "text trans");
- ggv_bin_read16(stream, "text font");
- ggv_bin_read16(stream, "text angle");
- lon = ggv_bin_read_double(stream, "text lon");
- lat = ggv_bin_read_double(stream, "text lat");
- ggv_bin_read_text16(stream, buf, "text label");
- waypt_name = QString::fromLatin1(buf.constData()).simplified();
- wpt = new Waypoint;
- wpt->longitude = lon;
- wpt->latitude = lat;
- wpt->description = waypt_name;
- waypt_add(wpt);
- break;
- case 0x03:
- // line
- case 0x04:
- // area
- ggv_bin_read16(stream, "line color");
- ggv_bin_read16(stream, "line width");
- ggv_bin_read16(stream, "line type");
- line_points = ggv_bin_read16(stream, "line points");
- ggv_bin_track = new route_head;
- track_add_head(ggv_bin_track);
- if (! track_name.isEmpty()) {
- ggv_bin_track->rte_name = track_name;
- }
-
- for (int i = 1; i <= line_points; i++) {
- lon = ggv_bin_read_double(stream, "line lon");
- lat = ggv_bin_read_double(stream, "line lat");
- wpt = new Waypoint;
- wpt->longitude = lon;
- wpt->latitude = lat;
- track_add_wpt(ggv_bin_track, wpt);
- }
- break;
- case 0x05:
- // rectangle
- case 0x06:
- // circle
- case 0x07:
- // triangle
- ggv_bin_read16(stream, "geom color");
- ggv_bin_read16(stream, "geom prop1");
- ggv_bin_read16(stream, "geom prop2");
- ggv_bin_read16(stream, "geom angle");
- ggv_bin_read16(stream, "geom stroke");
- ggv_bin_read16(stream, "geom area");
- ggv_bin_read_double(stream, "geom lon");
- ggv_bin_read_double(stream, "geom lat");
- break;
- case 0x09:
- ggv_bin_read16(stream, "bmp color");
- ggv_bin_read16(stream, "bmp prop1");
- ggv_bin_read16(stream, "bmp prop2");
- ggv_bin_read16(stream, "bmp prop3");
- ggv_bin_read_double(stream, "bmp lon");
- ggv_bin_read_double(stream, "bmp lat");
- ggv_bin_read_text32(stream, buf, "bmp data");
- break;
- default:
- fatal(MYNAME ": Unknown entry type (0x%hx, pos=0x%llx) \n", entry_type, entry_pos);
- }
- }
-}
-
-/***************************************************************************
- * OVL Version 3.0 and 4.0 *
- ***************************************************************************/
-
-void
-GgvBinFormat::ggv_bin_read_v34_header(QDataStream& stream, quint32& number_labels, quint32& number_records)
-{
- QByteArray buf;
-
- ggv_bin_read_bytes(stream, buf, 8, "unknown");
- number_labels = ggv_bin_read32(stream, "num labels");
- number_records = ggv_bin_read32(stream, "num records");
- ggv_bin_read_text16(stream, buf, "text label");
- ggv_bin_read16(stream, "unknown");
- ggv_bin_read16(stream, "unknown");
- // 8 bytes ending with 1E 00, contains len of header block
- ggv_bin_read16(stream, "unknown");
- quint16 header_len = ggv_bin_read16(stream, "header len");
- ggv_bin_read16(stream, "unknown");
- ggv_bin_read16(stream, "unknown");
- if (header_len > 0) {
- ggv_bin_read_bytes(stream, buf, header_len, "map name");
- buf.remove(0,4);
- buf.append('\0');
- if (global_opts.debug_level > 1) {
- qDebug() << "ovl: name =" << buf.constData();
- }
- }
-}
-
-void
-GgvBinFormat::ggv_bin_read_v34_label(QDataStream& stream)
-{
- QByteArray buf;
-
- if (global_opts.debug_level > 1) {
- qDebug("------------------------------------ 0x%llx", stream.device()->pos());
- }
- ggv_bin_read_bytes(stream, buf, 0x08, "label header");
- ggv_bin_read_bytes(stream, buf, 0x14, "label number");
- ggv_bin_read_text16(stream, buf, "label text");
- ggv_bin_read16(stream, "label flag1");
- ggv_bin_read16(stream, "label flag2");
-}
-
-QString
-GgvBinFormat::ggv_bin_read_v34_common(QDataStream& stream)
-{
- QByteArray buf;
-
- ggv_bin_read16(stream, "entry group");
- ggv_bin_read16(stream, "entry prop2");
- ggv_bin_read16(stream, "entry prop3");
- ggv_bin_read16(stream, "entry prop4");
- ggv_bin_read16(stream, "entry prop5");
- ggv_bin_read16(stream, "entry prop6");
- ggv_bin_read16(stream, "entry prop7");
- ggv_bin_read16(stream, "entry prop8");
- ggv_bin_read16(stream, "entry zoom");
- ggv_bin_read16(stream, "entry prop10");
- ggv_bin_read_text16(stream, buf, "entry txt");
- QString res = QString::fromLatin1(buf.constData()).simplified();
- quint16 type1 = ggv_bin_read16(stream, "entry type1");
- if (type1 != 1) {
- ggv_bin_read_text32(stream, buf, "entry object");
- }
- quint16 type2 = ggv_bin_read16(stream, "entry type2");
- if (type2 != 1) {
- ggv_bin_read_text32(stream, buf, "entry object");
- }
- return res;
-}
-
-void
-GgvBinFormat::ggv_bin_read_v34_record(QDataStream& stream)
-{
- QByteArray buf;
- Waypoint* wpt;
- route_head* ggv_bin_track;
- quint32 bmp_len;
- quint16 line_points;
- double lon, lat;
-
- if (global_opts.debug_level > 1) {
- qDebug("------------------------------------ 0x%llx", stream.device()->pos());
- }
-
- quint16 entry_type = ggv_bin_read16(stream, "entry type");
- QString label = ggv_bin_read_v34_common(stream);
-
- switch (entry_type) {
- case 0x02:
- // text
- ggv_bin_read16(stream, "text prop1");
- ggv_bin_read32(stream, "text prop2");
- ggv_bin_read16(stream, "text prop3");
- ggv_bin_read32(stream, "text prop4");
- ggv_bin_read16(stream, "text ltype");
- ggv_bin_read16(stream, "text angle");
- ggv_bin_read16(stream, "text size");
- ggv_bin_read16(stream, "text area");
- lon = ggv_bin_read_double(stream, "text lon");
- lat = ggv_bin_read_double(stream, "text lat");
- ggv_bin_read_double(stream, "text unk");
- ggv_bin_read_text16(stream, buf, "text label");
- wpt = new Waypoint;
- wpt->longitude = lon;
- wpt->latitude = lat;
- wpt->description = QString::fromLatin1(buf.constData()).simplified();
- waypt_add(wpt);
- break;
- case 0x03:
- case 0x04:
- // area
- case 0x17:
- // line
- ggv_bin_track = new route_head;
- track_add_head(ggv_bin_track);
-
- if (! label.isEmpty()) {
- ggv_bin_track->rte_name = label;
- }
-
- ggv_bin_read16(stream, "line prop1");
- ggv_bin_read32(stream, "line prop2");
- ggv_bin_read16(stream, "line prop3");
- ggv_bin_read32(stream, "line color");
- ggv_bin_read16(stream, "line size");
- ggv_bin_read16(stream, "line stroke");
- line_points = ggv_bin_read16(stream, "line points");
- if (entry_type == 0x04) {
- // found in example.ovl generated by Geogrid-Viewer 1.0
- ggv_bin_read16(stream, "line pad");
- }
-
- for (int i=1; i <= line_points; i++) {
- lon = ggv_bin_read_double(stream, "line lon");
- lat = ggv_bin_read_double(stream, "line lat");
- ggv_bin_read_double(stream, "line unk");
- wpt = new Waypoint;
- wpt->longitude = lon;
- wpt->latitude = lat;
- track_add_wpt(ggv_bin_track, wpt);
- }
- break;
- case 0x05:
- case 0x06:
- case 0x07:
- // circle
- ggv_bin_read16(stream, "circle prop1");
- ggv_bin_read32(stream, "circle prop2");
- ggv_bin_read16(stream, "circle prop3");
- ggv_bin_read32(stream, "circle color");
- ggv_bin_read32(stream, "circle prop5");
- ggv_bin_read32(stream, "circle prop6");
- ggv_bin_read16(stream, "circle ltype");
- ggv_bin_read16(stream, "circle angle");
- ggv_bin_read16(stream, "circle size");
- ggv_bin_read16(stream, "circle area");
- ggv_bin_read_double(stream, "circle lon");
- ggv_bin_read_double(stream, "circle lat");
- ggv_bin_read_double(stream, "circle unk");
- break;
- case 0x09:
- // bmp
- ggv_bin_read16(stream, "bmp prop1");
- ggv_bin_read32(stream, "bmp prop2");
- ggv_bin_read16(stream, "bmp prop3");
- ggv_bin_read32(stream, "bmp prop4");
- ggv_bin_read32(stream, "bmp prop5");
- ggv_bin_read32(stream, "bmp prop6");
- ggv_bin_read_double(stream, "bmp lon");
- ggv_bin_read_double(stream, "bmp lat");
- ggv_bin_read_double(stream, "bmp unk");
- bmp_len = ggv_bin_read32(stream, "bmp len");
- // The following check prevents passing an unsigned int with a
- // value greater than INT32_MAX to a signed int parameter in
- // ggv_bin_read_bytes later on. If this happens, the file is
- // almost certainly corrupted.
- if (bmp_len > INT32_MAX) {
- fatal(MYNAME ": Read error, max bmp_len exceeded\n");
- }
- ggv_bin_read16(stream, "bmp prop");
- ggv_bin_read_bytes(stream, buf, bmp_len, "bmp data");
- break;
- default:
- fatal(MYNAME ": Unsupported type: %x\n", entry_type);
- }
-}
-
-void
-GgvBinFormat::ggv_bin_read_v34(QDataStream& stream)
-{
- QByteArray buf;
- quint32 label_count;
- quint32 record_count;
-
- while (!stream.atEnd()) {
- ggv_bin_read_v34_header(stream, label_count, record_count);
-
- if (label_count && !stream.atEnd()) {
- if (global_opts.debug_level > 1) {
- qDebug("-----labels------------------------- 0x%llx", stream.device()->pos());
- }
- for (unsigned int i = 0; i < label_count; i++) {
- ggv_bin_read_v34_label(stream);
- }
- }
-
- if (record_count && !stream.atEnd()) {
- if (global_opts.debug_level > 1) {
- qDebug("-----records------------------------ 0x%llx", stream.device()->pos());
- }
- for (unsigned int i = 0; i < record_count; i++) {
- ggv_bin_read_v34_record(stream);
- }
- }
-
- if (!stream.atEnd()) {
- if (global_opts.debug_level > 1) {
- qDebug("------------------------------------ 0x%llx", stream.device()->pos());
- }
- // we just skip over the next magic bytes without checking they
- // contain the correct string. This is consistent with what I
- // believe GGV does
- ggv_bin_read_bytes(stream, buf, 23, "magicbytes");
- if (global_opts.debug_level > 1) {
- qDebug() << "ovl: header = " << buf.constData();
- }
- }
- }
-
- if (global_opts.debug_level > 1) {
- qDebug("fpos: 0x%llx", stream.device()->pos());
- qDebug("size: 0x%llx", stream.device()->size());
- }
-}
-
-/***************************************************************************
- * entry points called by gpsbabel main process *
- ***************************************************************************/
-
-void
-GgvBinFormat::read()
-{
- QFile file(read_fname);
- if (!file.open(QIODevice::ReadOnly)) {
- fatal(MYNAME ": Error opening file %s\n", qPrintable(read_fname));
- }
-
- QDataStream stream(&file);
- stream.setFloatingPointPrecision(QDataStream::DoublePrecision);
- stream.setByteOrder(QDataStream::LittleEndian);
-
- QByteArray buf;
- ggv_bin_read_bytes(stream, buf, 0x17, "magic");
- buf.append('\0');
- if (global_opts.debug_level > 1) {
- qDebug() << "ovl: header =" << buf.constData();
- }
-
- if (buf.startsWith("DOMGVCRD Ovlfile V2.0")) {
- ggv_bin_read_v2(stream);
- } else if (buf.startsWith("DOMGVCRD Ovlfile V3.0")) {
- ggv_bin_read_v34(stream);
- } else if (buf.startsWith("DOMGVCRD Ovlfile V4.0")) {
- ggv_bin_read_v34(stream);
- } else {
- fatal(MYNAME ": Unsupported file format\n");
- }
-
- file.close();
-}
-
-void
-GgvBinFormat::rd_init(const QString& fname)
-{
- read_fname = fname;
-}
-
-void
-GgvBinFormat::rd_deinit()
-{
- read_fname.clear();
-}
-
+++ /dev/null
-/*
-
- Handle Geogrid-Viewer binary overlay file format (.ovl)
-
- Copyright (C) 2016-2020 Ralf Horstmann <ralf@ackstorm.de>
- Copyright (C) 2016-2020 Robert Lipe, robertlipe+source@gpsbabel.org
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-*/
-#ifndef GGV_BIN_H_INCLUDED_
-#define GGV_BIN_H_INCLUDED_
-
-#include "defs.h"
-#include "format.h"
-
-
-class GgvBinFormat : public Format
-{
-public:
- ff_type get_type() const override
- {
- return ff_type_file;
- }
-
- QVector<ff_cap> get_cap() const override
- {
- return {
- ff_cap_none, // waypoints
- ff_cap_read, // tracks
- ff_cap_none // routes
- };
- }
-
- QString get_encode() const override
- {
- return CET_CHARSET_ASCII;
- }
-
- int get_fixed_encode() const override
- {
- return 0;
- }
-
- void rd_init(const QString& fname) override;
- void read() override;
- void rd_deinit() override;
-
-private:
- static void ggv_bin_read_bytes(QDataStream& stream, QByteArray& buf, int len, const char* descr = nullptr);
- static quint16 ggv_bin_read16(QDataStream& stream, const char* descr = nullptr);
- static quint32 ggv_bin_read32(QDataStream& stream, const char* descr = nullptr);
- static void ggv_bin_read_text16(QDataStream& stream, QByteArray& buf, const char* descr = nullptr);
- static void ggv_bin_read_text32(QDataStream& stream, QByteArray& buf, const char* descr = nullptr);
- static double ggv_bin_read_double(QDataStream& stream, const char* descr = nullptr);
- static void ggv_bin_read_v2(QDataStream& stream);
- static void ggv_bin_read_v34_header(QDataStream& stream, quint32& number_labels, quint32& number_records);
- static void ggv_bin_read_v34_label(QDataStream& stream);
- static QString ggv_bin_read_v34_common(QDataStream& stream);
- static void ggv_bin_read_v34_record(QDataStream& stream);
- static void ggv_bin_read_v34(QDataStream& stream);
-
- QString read_fname;
-
-};
-
-#endif
+++ /dev/null
-/*
-
- Support for "GeoGrid Viewer ascii overlay files".
-
- Copyright (C) 2008 Olaf Klein (o.b.klein@gpsbabel.org).
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
- */
-
-#include <cmath> // for sin, cos, acos
-
-#include <QString> // for QString
-#include <QVector> // for QVector
-#include <QtGlobal> // for foreach
-
-#include "defs.h"
-#include "gbfile.h" // for gbfprintf, gbfclose, gbfopen, gbfile
-#include "grtcirc.h" // for RAD, gcdist, DEG
-#include "inifile.h" // for inifile_readstr, inifile_readint_def, inifile_done, inifile_init, inifile_readint, inifile_t
-
-
-#define MYNAME "ggv_ovl"
-
-static
-QVector<arglist_t> ggv_ovl_args = {
-};
-
-enum OVL_SYMBOL_TYP {
- OVL_SYMBOL_BITMAP = 1,
- OVL_SYMBOL_TEXT,
- OVL_SYMBOL_LINE,
- OVL_SYMBOL_POLYGON,
- OVL_SYMBOL_RECTANGLE,
- OVL_SYMBOL_CIRCLE,
- OVL_SYMBOL_TRIANGLE
-};
-
-enum OVL_COLOR_TYP {
- OVL_COLOR_RED = 1, /* = 1 */
- OVL_COLOR_LIME, /* = 2 */
- OVL_COLOR_BLUE, /* = 3 */
- OVL_COLOR_YELLOW, /* = 4 */
- OVL_COLOR_BLACK, /* = 5 */
- OVL_COLOR_WHITE, /* = 6 */
- OVL_COLOR_7, /* = 7 (draws only a simple line) */
- OVL_COLOR_FUCHSIA, /* = 8 */
- OVL_COLOR_AQUA, /* = 9 */
-};
-
-/* some hints:
- # "col": color
- # "group": 1 means NO GROUP
- # "size": size in pixels PLUS 100
- # "with":
- # "zoom":
- # "art": line-style
- */
-static inifile_t* inifile;
-static gbfile* fout;
-
-static int symbol_ct; /* Number of symbols written */
-static int group_ct; /* Group number during write */
-static int track_ct, route_ct;
-static bounds all_bounds;
-static OVL_COLOR_TYP color;
-
-/*******************************************************************************
-* %%% global callbacks called by gpsbabel main process %%% *
-*******************************************************************************/
-
-static void
-ggv_ovl_rd_init(const QString& fname)
-{
- inifile = inifile_init(fname, MYNAME);
-
- route_ct = 0;
- track_ct = 0;
-}
-
-static void
-ggv_ovl_rd_deinit()
-{
- inifile_done(inifile);
-}
-
-static void
-ggv_ovl_read()
-{
- int symbols = inifile_readint_def(inifile, "Overlay", "Symbols", -1);
-
- for (int i = 1; i <= symbols; ++i) {
-
- QString symbol = QString("Symbol %1").arg(i);
-
- OVL_SYMBOL_TYP type = (OVL_SYMBOL_TYP) inifile_readint_def(inifile, symbol, "Typ", 0);
- int points = inifile_readint_def(inifile, symbol, "Punkte", -1);
-
- QString lat;
- QString lon;
- switch (type) {
-
- Waypoint* wpt;
- int group;
-
- case OVL_SYMBOL_LINE:
- case OVL_SYMBOL_POLYGON:
-
- if (!inifile_readint(inifile, symbol, "Group", &group)) {
- group = -1;
- }
-
- if (points > 0) {
- route_head* trk;
-
- auto* rte = trk = new route_head;
- if (group > 1) {
- route_add_head(rte);
- route_ct++;
- rte->rte_name = QString("Route %1").arg(route_ct);
- } else {
- track_add_head(trk);
- track_ct++;
- trk->rte_name = QString("Track %1").arg(track_ct);
- }
-
- for (int j = 0; j < points; ++j) {
-
- wpt = new Waypoint;
-
- lat = inifile_readstr(inifile, symbol, QString("YKoord%1").arg(j));
- if (lat.isNull()) {
- delete wpt;
- continue;
- }
- wpt->latitude = lat.toDouble();
-
- lon = inifile_readstr(inifile, symbol, QString("XKoord%1").arg(j));
- if (lon.isNull()) {
- delete wpt;
- continue;
- }
- wpt->longitude = lon.toDouble();
-
- if (group > 1) {
- route_add_wpt(rte, wpt);
- } else {
- track_add_wpt(trk, wpt);
- }
- }
- }
- break;
-
- case OVL_SYMBOL_CIRCLE:
- case OVL_SYMBOL_TRIANGLE:
-
- wpt = new Waypoint;
- wpt->shortname = symbol;
-
- lat = inifile_readstr(inifile, symbol, "YKoord");
- if (lat.isNull()) {
- delete wpt;
- continue;
- }
- wpt->latitude = lat.toDouble();
- lon = inifile_readstr(inifile, symbol, "XKoord");
- if (lon.isNull()) {
- delete wpt;
- continue;
- }
- wpt->longitude = lon.toDouble();
-
- waypt_add(wpt);
- break;
-
- case OVL_SYMBOL_BITMAP:
- case OVL_SYMBOL_TEXT:
- case OVL_SYMBOL_RECTANGLE:
- break;
- }
- }
-}
-
-/**************************************************************************/
-
-/* prototypes used in main functions */
-
-static void waypt_disp_cb(const Waypoint* wpt);
-static void track_disp_cb(const route_head* trk);
-static void route_disp_cb(const route_head* rte);
-static void write_bounds();
-static void draw_symbol_basics(OVL_SYMBOL_TYP typ, int art, OVL_COLOR_TYP color, const Waypoint* wpt);
-static int get_direction(const Waypoint* A, const Waypoint* B);
-// static void draw_symbol_text(const char *text, const waypoint *reference);
-
-/* -----------------------------------------------------------------------*/
-
-static void
-ggv_ovl_wr_init(const QString& fname)
-{
- fout = gbfopen(fname, "w", MYNAME);
-
- symbol_ct = 0;
-}
-
-static void
-ggv_ovl_wr_deinit()
-{
- gbfclose(fout);
-}
-
-static void
-ggv_ovl_write()
-{
- group_ct = 1; /* tracks are not grouped */
- color = OVL_COLOR_FUCHSIA;
- track_disp_all(track_disp_cb, nullptr, nullptr);
-
- group_ct++;
- color = OVL_COLOR_AQUA;
- route_disp_all(route_disp_cb, nullptr, nullptr);
-
- group_ct++;
- color = OVL_COLOR_LIME;
- waypt_disp_all(waypt_disp_cb);
-
- gbfprintf(fout, "[Overlay]\n");
- gbfprintf(fout, "Symbols=%d\n", symbol_ct);
- gbfprintf(fout, "[MapLage]\n");
- gbfprintf(fout, "MapName=Bundesrepublik 1:1 Mio\n");
- gbfprintf(fout, "DimmFc=100\n");
- gbfprintf(fout, "ZoomFc=100\n");
- write_bounds();
- gbfprintf(fout, "RefOn=0\n"); /* no reference point */
-}
-
-/**************************************************************************/
-
-static void
-waypt_disp_cb(const Waypoint* wpt)
-{
- draw_symbol_basics(OVL_SYMBOL_CIRCLE, 1, color, wpt);
- gbfprintf(fout, "Width=20\n");
- gbfprintf(fout, "Height=20\n");
- gbfprintf(fout, "Dir=100\n");
- gbfprintf(fout, "Zoom=1\n");
- gbfprintf(fout, "Size=102\n");
- gbfprintf(fout, "Area=2\n");
-// draw_symbol_text(wpt->shortname, wpt);
-}
-
-/* -----------------------------------------------------------------------*/
-
-static void
-track_disp_cb(const route_head* trk)
-{
- int waypt_ct = trk->rte_waypt_ct();
-
- if (waypt_ct <= 0) {
- return;
- }
-
- draw_symbol_basics(OVL_SYMBOL_LINE, 1, color, nullptr);
-
- gbfprintf(fout, "Zoom=1\n");
- gbfprintf(fout, "Size=105\n");
- gbfprintf(fout, "Punkte=%d\n", waypt_ct);
-
- int i = 0;
-
- foreach (const Waypoint* wpt, trk->waypoint_list) {
-
- gbfprintf(fout, "XKoord%d=%0.8f\n", i, wpt->longitude);
- gbfprintf(fout, "YKoord%d=%0.8f\n", i, wpt->latitude);
-
- i++;
- }
-}
-
-/* -----------------------------------------------------------------------*/
-
-static void
-route_disp_cb(const route_head* rte)
-{
- int waypt_ct = rte->rte_waypt_ct();
-
- if (waypt_ct <= 0) {
- return;
- }
-
- track_disp_cb(rte); /* draw a line as tracks */
-
- color = OVL_COLOR_RED;
-
- int i = 0;
- const Waypoint* prev = nullptr;
-
- foreach (const Waypoint* wpt, rte->waypoint_list) {
-
- if (prev != nullptr) {
- draw_symbol_basics(OVL_SYMBOL_TRIANGLE, 1, (OVL_COLOR_TYP)9 /* color */, prev);
-
- gbfprintf(fout, "Width=12\n");
- gbfprintf(fout, "Height=8\n");
- gbfprintf(fout, "Dir=%d\n", 100 + get_direction(prev, wpt));
- gbfprintf(fout, "Zoom=1\n");
- gbfprintf(fout, "Size=101\n");
- gbfprintf(fout, "Area=2\n");
- }
-
- i++;
- prev = wpt;
- }
-}
-
-/* -----------------------------------------------------------------------*/
-
-static void
-waypt_bound_calc(const Waypoint* waypointp)
-{
- waypt_add_to_bounds(&all_bounds, waypointp);
-}
-
-static void
-write_bounds()
-{
- waypt_init_bounds(&all_bounds);
-
- waypt_disp_all(waypt_bound_calc);
- route_disp_all(nullptr, nullptr, waypt_bound_calc);
- track_disp_all(nullptr, nullptr, waypt_bound_calc);
-
- if (waypt_bounds_valid(&all_bounds)) {
-
- double cx = all_bounds.min_lat + ((all_bounds.max_lat - all_bounds.min_lat) / 2);
- double cy = all_bounds.min_lon + ((all_bounds.max_lon - all_bounds.min_lon) / 2);
-
- gbfprintf(fout, "CenterLat=%0.8f\n", cx);
- gbfprintf(fout, "CenterLong=%0.8f\n", cy);
- } else {
- gbfprintf(fout, "CenterLong=10.52374295\n");
- gbfprintf(fout, "CenterLat=52.26474445\n");
- }
-}
-
-static void
-draw_symbol_basics(const OVL_SYMBOL_TYP typ, const int art,
- const OVL_COLOR_TYP point_color, const Waypoint* wpt)
-{
- symbol_ct++;
-
- gbfprintf(fout, "[Symbol %d]\n", symbol_ct);
- gbfprintf(fout, "Typ=%d\n", typ);
- gbfprintf(fout, "Group=%d\n", group_ct);
- gbfprintf(fout, "Col=%d\n", point_color);
- if (art >= 0) {
- gbfprintf(fout, "Art=%d\n", art);
- }
- if (wpt) {
- gbfprintf(fout, "XKoord=%.8f\n", wpt->longitude);
- gbfprintf(fout, "YKoord=%.8f\n", wpt->latitude);
- }
-}
-
-/* the following code comes from first overlay module */
-
-static int
-get_direction(const Waypoint* A, const Waypoint* B)
-{
- double lata = RAD(A->latitude);
- double lona = RAD(A->longitude);
- double latb = RAD(B->latitude);
- double lonb = RAD(B->longitude);
-
- double dist = gcdist(lata, lona, latb, lonb);
- double dir = acos((sin(latb) - sin(lata) * cos(dist)) / (cos(lata) * sin(dist)));
- if (lonb < lona) {
- dir = -dir;
- }
- int res = (int) DEG(dir);
- res = 360 - (res + 270);
- if (res < 0) {
- res += 360;
- } else if (res > 360) {
- res -= 360.0;
- }
-
- return res;
-}
-
-#if 0
-static void
-draw_symbol_text(const char* text, const Waypoint* reference)
-{
- Waypoint wpt;
-
- if ((reference == NULL) || (text == NULL)) {
- return;
- }
- if (*text == '\0') {
- return;
- }
-
- wpt = *reference;
-
- wpt.latitude = wpt.latitude + 0.015;
- wpt.longitude = wpt.longitude + 0.015;
-
- draw_symbol_basics(OVL_SYMBOL_TEXT, -1, OVL_COLOR_BLACK, &wpt);
-
- gbfprintf(fout, "Area=1\n");
- gbfprintf(fout, "Zoom=1\n");
- gbfprintf(fout, "Size=120\n");
- gbfprintf(fout, "Font=3\n");
- gbfprintf(fout, "Dir=100\n");
- gbfprintf(fout, "Text=%s\n", text);
-}
-#endif
-
-/**************************************************************************/
-
-ff_vecs_t ggv_ovl_vecs = {
- ff_type_file,
- FF_CAP_RW_ALL,
- ggv_ovl_rd_init,
- ggv_ovl_wr_init,
- ggv_ovl_rd_deinit,
- ggv_ovl_wr_deinit,
- ggv_ovl_read,
- ggv_ovl_write,
- nullptr,
- &ggv_ovl_args,
- CET_CHARSET_MS_ANSI, 0
- , NULL_POS_OPS
-};
-
-/**************************************************************************/
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<gpx version="1.0" creator="GPSBabel - https://www.gpsbabel.org" xmlns="http://www.topografix.com/GPX/1/0">
- <time>1970-01-01T00:00:00Z</time>
- <bounds minlat="48.270182777" minlon="11.123582605" maxlat="48.272877253" maxlon="11.131655554"/>
- <trk>
- <trkseg>
- <trkpt lat="48.270464676" lon="11.126680138"/>
- <trkpt lat="48.270388035" lon="11.128432438"/>
- <trkpt lat="48.270399219" lon="11.129913865"/>
- <trkpt lat="48.270588124" lon="11.131122911"/>
- <trkpt lat="48.270951717" lon="11.131655554"/>
- <trkpt lat="48.271741381" lon="11.129083025"/>
- <trkpt lat="48.271821089" lon="11.127734716"/>
- <trkpt lat="48.272355299" lon="11.127052185"/>
- <trkpt lat="48.272707696" lon="11.126103325"/>
- <trkpt lat="48.272877253" lon="11.124753460"/>
- <trkpt lat="48.272425789" lon="11.124491733"/>
- <trkpt lat="48.271704673" lon="11.124234594"/>
- <trkpt lat="48.271163324" lon="11.123974406"/>
- <trkpt lat="48.270441183" lon="11.123582605"/>
- <trkpt lat="48.270182777" lon="11.125068613"/>
- <trkpt lat="48.270464676" lon="11.126680138"/>
- </trkseg>
- </trk>
-</gpx>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<gpx version="1.0" creator="GPSBabel - https://www.gpsbabel.org" xmlns="http://www.topografix.com/GPX/1/0">
- <time>1970-01-01T00:00:00Z</time>
- <bounds minlat="51.390787309" minlon="7.634582135" maxlat="51.416622730" maxlon="7.670407825"/>
- <wpt lat="51.400591976" lon="7.655250113">
- <name>Beispiel-Text</name>
- <cmt>Beispiel-Text</cmt>
- <desc>Beispiel-Text</desc>
- </wpt>
- <trk>
- <name>Linie</name>
- <trkseg>
- <trkpt lat="51.416622730" lon="7.634582135"/>
- <trkpt lat="51.413106821" lon="7.637561773"/>
- <trkpt lat="51.409758874" lon="7.639529832"/>
- <trkpt lat="51.407628129" lon="7.641820840"/>
- <trkpt lat="51.406255307" lon="7.643586185"/>
- <trkpt lat="51.403222581" lon="7.645616042"/>
- <trkpt lat="51.399781311" lon="7.647298422"/>
- <trkpt lat="51.398632218" lon="7.648984855"/>
- <trkpt lat="51.397982280" lon="7.651087602"/>
- <trkpt lat="51.398325694" lon="7.653592205"/>
- <trkpt lat="51.398944395" lon="7.656591723"/>
- <trkpt lat="51.398664437" lon="7.659617592"/>
- <trkpt lat="51.396813518" lon="7.662832934"/>
- <trkpt lat="51.393519865" lon="7.665658933"/>
- <trkpt lat="51.390787309" lon="7.670407825"/>
- </trkseg>
- </trk>
- <trk>
- <name>Fläche</name>
- <trkseg>
- <trkpt lat="51.402506568" lon="7.653684988"/>
- <trkpt lat="51.403988399" lon="7.653569612"/>
- <trkpt lat="51.406267829" lon="7.656377105"/>
- <trkpt lat="51.404428210" lon="7.656646600"/>
- <trkpt lat="51.403620311" lon="7.656742131"/>
- <trkpt lat="51.402285607" lon="7.657930916"/>
- <trkpt lat="51.401834671" lon="7.657800408"/>
- <trkpt lat="51.402486377" lon="7.655841237"/>
- <trkpt lat="51.402417535" lon="7.653759457"/>
- <trkpt lat="51.402506568" lon="7.653684988"/>
- </trkseg>
- </trk>
-</gpx>
+++ /dev/null
-[Symbol 1]
-Typ=3
-Group=1
-Col=3
-Zoom=1
-Size=102
-Art=1
-Punkte=37
-XKoord0=10.65544468
-YKoord0=51.76587580
-XKoord1=10.65218499
-YKoord1=51.76785421
-XKoord2=10.64862029
-YKoord2=51.77140983
-XKoord3=10.64497174
-YKoord3=51.77267441
-XKoord4=10.64177929
-YKoord4=51.77253927
-XKoord5=10.63658709
-YKoord5=51.77319595
-XKoord6=10.63379175
-YKoord6=51.77202137
-XKoord7=10.62861368
-YKoord7=51.77105955
-XKoord8=10.62724928
-YKoord8=51.77139306
-XKoord9=10.63186918
-YKoord9=51.77294694
-XKoord10=10.63254193
-YKoord10=51.77352186
-XKoord11=10.62848613
-YKoord11=51.77757803
-XKoord12=10.62817257
-YKoord12=51.77893066
-XKoord13=10.62717649
-YKoord13=51.77943882
-XKoord14=10.62589235
-YKoord14=51.77999590
-XKoord15=10.62677915
-YKoord15=51.78047801
-XKoord16=10.63320509
-YKoord16=51.77984957
-XKoord17=10.63871707
-YKoord17=51.77999757
-XKoord18=10.64266096
-YKoord18=51.77886389
-XKoord19=10.64411748
-YKoord19=51.77906825
-XKoord20=10.64505184
-YKoord20=51.78085288
-XKoord21=10.64760783
-YKoord21=51.78140135
-XKoord22=10.64750964
-YKoord22=51.78666102
-XKoord23=10.64666131
-YKoord23=51.78923465
-XKoord24=10.64432653
-YKoord24=51.79079540
-XKoord25=10.64342137
-YKoord25=51.78981930
-XKoord26=10.64058175
-YKoord26=51.78945448
-XKoord27=10.64087544
-YKoord27=51.78756280
-XKoord28=10.63828988
-YKoord28=51.78620563
-XKoord29=10.63477916
-YKoord29=51.78531071
-XKoord30=10.63145721
-YKoord30=51.78562653
-XKoord31=10.62874861
-YKoord31=51.78687753
-XKoord32=10.62751729
-YKoord32=51.78689459
-XKoord33=10.61656675
-YKoord33=51.79477582
-XKoord34=10.62139475
-YKoord34=51.79601267
-XKoord35=10.62075568
-YKoord35=51.79840345
-XKoord36=10.61712344
-YKoord36=51.80020623
-[Symbol 2]
-Typ=5
-Group=1
-Width=40
-Height=40
-Dir=145
-Art=1
-Col=1
-Zoom=1
-Size=102
-Area=6
-XKoord=10.60357219
-YKoord=51.80439171
-[Symbol 3]
-Typ=2
-Group=1
-Col=1
-Area=1
-Zoom=1
-Size=140
-Font=1
-Dir=100
-XKoord=10.61397192
-YKoord=51.80532805
-Text=Test Text
-[Symbol 4]
-Typ=3
-Group=1
-Col=1
-Zoom=1
-Size=102
-Art=1
-Punkte=12
-XKoord0=10.68674217
-YKoord0=51.74466700
-XKoord1=10.69060221
-YKoord1=51.74721824
-XKoord2=10.68813476
-YKoord2=51.74900651
-XKoord3=10.68544330
-YKoord3=51.75061815
-XKoord4=10.67975602
-YKoord4=51.75150857
-XKoord5=10.68459226
-YKoord5=51.75498985
-XKoord6=10.68366920
-YKoord6=51.75743002
-XKoord7=10.67707586
-YKoord7=51.76125458
-XKoord8=10.66885560
-YKoord8=51.76420301
-XKoord9=10.66582832
-YKoord9=51.76460551
-XKoord10=10.66341456
-YKoord10=51.76396555
-XKoord11=10.65859717
-YKoord11=51.76493250
-[Symbol 5]
-Typ=3
-Group=9
-Col=1
-Zoom=1
-Size=104
-Art=1
-Punkte=15
-XKoord0=10.55206839
-YKoord0=51.78445444
-XKoord1=10.55532307
-YKoord1=51.78427659
-XKoord2=10.56091250
-YKoord2=51.78456204
-XKoord3=10.56554552
-YKoord3=51.78652284
-XKoord4=10.56815308
-YKoord4=51.78648808
-XKoord5=10.57172940
-YKoord5=51.78513698
-XKoord6=10.57786274
-YKoord6=51.78231334
-XKoord7=10.57811951
-YKoord7=51.78136609
-XKoord8=10.57780475
-YKoord8=51.78065123
-XKoord9=10.57627448
-YKoord9=51.78040211
-XKoord10=10.57496306
-YKoord10=51.78019497
-XKoord11=10.57412889
-YKoord11=51.77912753
-XKoord12=10.57307126
-YKoord12=51.77788331
-XKoord13=10.57426483
-YKoord13=51.77678870
-XKoord14=10.57768755
-YKoord14=51.77521476
-[Symbol 6]
-Typ=4
-Group=9
-Art=1
-Col=1
-Area=5
-Zoom=1
-Size=102
-Punkte=5
-XKoord0=10.59652507
-YKoord0=51.80188093
-XKoord1=10.60803867
-YKoord1=51.79938689
-XKoord2=10.58909290
-YKoord2=51.79263370
-XKoord3=10.57832128
-YKoord3=51.80181232
-XKoord4=10.59314542
-YKoord4=51.80269083
-[Symbol 7]
-Typ=3
-Group=17
-Col=2
-Zoom=1
-Size=105
-Art=3
-Punkte=4
-XKoord0=10.60657924
-YKoord0=51.76255405
-XKoord1=10.59852740
-YKoord1=51.76630420
-XKoord2=10.59033233
-YKoord2=51.76807826
-XKoord3=10.58660071
-YKoord3=51.77527456
-[Symbol 8]
-Typ=4
-Group=17
-Art=1
-Col=1
-Area=7
-Zoom=1
-Size=102
-Punkte=5
-XKoord0=10.61041078
-YKoord0=51.76438920
-XKoord1=10.60638215
-YKoord1=51.75496141
-XKoord2=10.62417615
-YKoord2=51.75237979
-XKoord3=10.62512771
-YKoord3=51.76274845
-XKoord4=10.61706616
-YKoord4=51.76618541
-[Symbol 9]
-Typ=4
-Group=1
-Art=1
-Col=1
-Area=4
-Zoom=1
-Size=102
-Punkte=6
-XKoord0=10.63694247
-YKoord0=51.81103276
-XKoord1=10.62712184
-YKoord1=51.80006827
-XKoord2=10.64282436
-YKoord2=51.79333319
-XKoord3=10.66695026
-YKoord3=51.80094843
-XKoord4=10.64989768
-YKoord4=51.81237972
-XKoord5=10.63068244
-YKoord5=51.81637803
-[Overlay]
-Symbols=9
-[MapLage]
-MapName=Top. Karte 1:50.000 Nieders.
-DimmFc=100
-ZoomFc=141
-CenterLat=51.79222626
-CenterLong=10.62546251
-RefOn=0
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<gpx version="1.0" creator="GPSBabel - https://www.gpsbabel.org" xmlns="http://www.topografix.com/GPX/1/0">
- <time>1970-01-01T00:00:00Z</time>
- <bounds minlat="51.744667000" minlon="10.552068390" maxlat="51.816378030" maxlon="10.690602210"/>
- <rte>
- <name>Route 1</name>
- <rtept lat="51.784454440" lon="10.552068390">
- <name>RPT001</name>
- </rtept>
- <rtept lat="51.784276590" lon="10.555323070">
- <name>RPT002</name>
- </rtept>
- <rtept lat="51.784562040" lon="10.560912500">
- <name>RPT003</name>
- </rtept>
- <rtept lat="51.786522840" lon="10.565545520">
- <name>RPT004</name>
- </rtept>
- <rtept lat="51.786488080" lon="10.568153080">
- <name>RPT005</name>
- </rtept>
- <rtept lat="51.785136980" lon="10.571729400">
- <name>RPT006</name>
- </rtept>
- <rtept lat="51.782313340" lon="10.577862740">
- <name>RPT007</name>
- </rtept>
- <rtept lat="51.781366090" lon="10.578119510">
- <name>RPT008</name>
- </rtept>
- <rtept lat="51.780651230" lon="10.577804750">
- <name>RPT009</name>
- </rtept>
- <rtept lat="51.780402110" lon="10.576274480">
- <name>RPT010</name>
- </rtept>
- <rtept lat="51.780194970" lon="10.574963060">
- <name>RPT011</name>
- </rtept>
- <rtept lat="51.779127530" lon="10.574128890">
- <name>RPT012</name>
- </rtept>
- <rtept lat="51.777883310" lon="10.573071260">
- <name>RPT013</name>
- </rtept>
- <rtept lat="51.776788700" lon="10.574264830">
- <name>RPT014</name>
- </rtept>
- <rtept lat="51.775214760" lon="10.577687550">
- <name>RPT015</name>
- </rtept>
- </rte>
- <rte>
- <name>Route 2</name>
- <rtept lat="51.801880930" lon="10.596525070">
- <name>RPT016</name>
- </rtept>
- <rtept lat="51.799386890" lon="10.608038670">
- <name>RPT017</name>
- </rtept>
- <rtept lat="51.792633700" lon="10.589092900">
- <name>RPT018</name>
- </rtept>
- <rtept lat="51.801812320" lon="10.578321280">
- <name>RPT019</name>
- </rtept>
- <rtept lat="51.802690830" lon="10.593145420">
- <name>RPT020</name>
- </rtept>
- </rte>
- <rte>
- <name>Route 3</name>
- <rtept lat="51.762554050" lon="10.606579240">
- <name>RPT021</name>
- </rtept>
- <rtept lat="51.766304200" lon="10.598527400">
- <name>RPT022</name>
- </rtept>
- <rtept lat="51.768078260" lon="10.590332330">
- <name>RPT023</name>
- </rtept>
- <rtept lat="51.775274560" lon="10.586600710">
- <name>RPT024</name>
- </rtept>
- </rte>
- <rte>
- <name>Route 4</name>
- <rtept lat="51.764389200" lon="10.610410780">
- <name>RPT025</name>
- </rtept>
- <rtept lat="51.754961410" lon="10.606382150">
- <name>RPT026</name>
- </rtept>
- <rtept lat="51.752379790" lon="10.624176150">
- <name>RPT027</name>
- </rtept>
- <rtept lat="51.762748450" lon="10.625127710">
- <name>RPT028</name>
- </rtept>
- <rtept lat="51.766185410" lon="10.617066160">
- <name>RPT029</name>
- </rtept>
- </rte>
- <trk>
- <name>Track 1</name>
- <trkseg>
- <trkpt lat="51.765875800" lon="10.655444680"/>
- <trkpt lat="51.767854210" lon="10.652184990"/>
- <trkpt lat="51.771409830" lon="10.648620290"/>
- <trkpt lat="51.772674410" lon="10.644971740"/>
- <trkpt lat="51.772539270" lon="10.641779290"/>
- <trkpt lat="51.773195950" lon="10.636587090"/>
- <trkpt lat="51.772021370" lon="10.633791750"/>
- <trkpt lat="51.771059550" lon="10.628613680"/>
- <trkpt lat="51.771393060" lon="10.627249280"/>
- <trkpt lat="51.772946940" lon="10.631869180"/>
- <trkpt lat="51.773521860" lon="10.632541930"/>
- <trkpt lat="51.777578030" lon="10.628486130"/>
- <trkpt lat="51.778930660" lon="10.628172570"/>
- <trkpt lat="51.779438820" lon="10.627176490"/>
- <trkpt lat="51.779995900" lon="10.625892350"/>
- <trkpt lat="51.780478010" lon="10.626779150"/>
- <trkpt lat="51.779849570" lon="10.633205090"/>
- <trkpt lat="51.779997570" lon="10.638717070"/>
- <trkpt lat="51.778863890" lon="10.642660960"/>
- <trkpt lat="51.779068250" lon="10.644117480"/>
- <trkpt lat="51.780852880" lon="10.645051840"/>
- <trkpt lat="51.781401350" lon="10.647607830"/>
- <trkpt lat="51.786661020" lon="10.647509640"/>
- <trkpt lat="51.789234650" lon="10.646661310"/>
- <trkpt lat="51.790795400" lon="10.644326530"/>
- <trkpt lat="51.789819300" lon="10.643421370"/>
- <trkpt lat="51.789454480" lon="10.640581750"/>
- <trkpt lat="51.787562800" lon="10.640875440"/>
- <trkpt lat="51.786205630" lon="10.638289880"/>
- <trkpt lat="51.785310710" lon="10.634779160"/>
- <trkpt lat="51.785626530" lon="10.631457210"/>
- <trkpt lat="51.786877530" lon="10.628748610"/>
- <trkpt lat="51.786894590" lon="10.627517290"/>
- <trkpt lat="51.794775820" lon="10.616566750"/>
- <trkpt lat="51.796012670" lon="10.621394750"/>
- <trkpt lat="51.798403450" lon="10.620755680"/>
- <trkpt lat="51.800206230" lon="10.617123440"/>
- </trkseg>
- </trk>
- <trk>
- <name>Track 2</name>
- <trkseg>
- <trkpt lat="51.744667000" lon="10.686742170"/>
- <trkpt lat="51.747218240" lon="10.690602210"/>
- <trkpt lat="51.749006510" lon="10.688134760"/>
- <trkpt lat="51.750618150" lon="10.685443300"/>
- <trkpt lat="51.751508570" lon="10.679756020"/>
- <trkpt lat="51.754989850" lon="10.684592260"/>
- <trkpt lat="51.757430020" lon="10.683669200"/>
- <trkpt lat="51.761254580" lon="10.677075860"/>
- <trkpt lat="51.764203010" lon="10.668855600"/>
- <trkpt lat="51.764605510" lon="10.665828320"/>
- <trkpt lat="51.763965550" lon="10.663414560"/>
- <trkpt lat="51.764932500" lon="10.658597170"/>
- </trkseg>
- </trk>
- <trk>
- <name>Track 3</name>
- <trkseg>
- <trkpt lat="51.811032760" lon="10.636942470"/>
- <trkpt lat="51.800068270" lon="10.627121840"/>
- <trkpt lat="51.793333190" lon="10.642824360"/>
- <trkpt lat="51.800948430" lon="10.666950260"/>
- <trkpt lat="51.812379720" lon="10.649897680"/>
- <trkpt lat="51.816378030" lon="10.630682440"/>
- </trkseg>
- </trk>
-</gpx>
+++ /dev/null
-#
-# Geogrid-Viewer binary overlay files
-#
-rm -f ${TMPDIR}/ggv_bin*
-gpsbabel -i ggv_bin -f ${REFERENCE}/ggv_bin-sample-v2.ovl -o gpx -F ${TMPDIR}/ggv_bin-sample-v2.gpx
-compare ${REFERENCE}/ggv_bin-sample-v2.gpx ${TMPDIR}/ggv_bin-sample-v2.gpx
-gpsbabel -i ggv_bin -f ${REFERENCE}/ggv_bin-sample-v3.ovl -o gpx -F ${TMPDIR}/ggv_bin-sample-v3.gpx
-compare ${REFERENCE}/ggv_bin-sample-v3.gpx ${TMPDIR}/ggv_bin-sample-v3.gpx
+++ /dev/null
-
-#
-# ggv_ovl 'Geogrid Viewer ascii overlay files'
-#
-gpsbabel -i ggv_ovl -f ${REFERENCE}/ggv_ovl.ovl -o gpx -F ${TMPDIR}/ggv_ovl~ovl.gpx
-compare ${REFERENCE}/ggv_ovl~ovl.gpx ${TMPDIR}/ggv_ovl~ovl.gpx
-
#include "gbversion.h" // for WEB_DOC_DIR
#include "gdb.h" // for GdbFormat
#include "geojson.h" // for GeoJsonFormat
-#include "ggv_bin.h" // for GgvBinFormat
#include "globalsat_sport.h" // for GlobalsatSportFormat
#include "gpx.h" // for GpxFormat
#include "gtrnctr.h" // for GtrnctrFormat
extern ff_vecs_t igo8_vecs;
extern ff_vecs_t mapasia_tr7_vecs;
extern ff_vecs_t navitel_trk_vecs;
-extern ff_vecs_t ggv_ovl_vecs;
extern ff_vecs_t itracku_vecs;
extern ff_vecs_t itracku_fvecs;
extern ff_vecs_t sbp_vecs;
HumminbirdHTFormat humminbird_ht_fmt;
LegacyFormat mapasia_tr7_fmt {mapasia_tr7_vecs};
LegacyFormat navitel_trk_fmt {navitel_trk_vecs};
- LegacyFormat ggv_ovl_fmt {ggv_ovl_vecs};
LegacyFormat itracku_fmt {itracku_vecs};
LegacyFormat itracku_ffmt {itracku_fvecs};
LegacyFormat sbp_fmt {sbp_vecs};
EnergymproFormat energympro_fmt;
MyNavFormat mynav_fmt;
GeoJsonFormat geojson_fmt;
- GgvBinFormat ggv_bin_fmt;
GlobalsatSportFormat globalsat_sport_fmt;
QstarzBL1000Format qstarz_bl_1000_fmt;
#endif // MAXIMAL_ENABLED
+++ /dev/null
-<para>
- Binary overlay files (.ovl) used by
- <productname>Geogrid</productname>-Viewer.
-</para>
-<para>
- Geogrid-Viewer is part of several
- <ulink url="https://de.wikipedia.org/wiki/Top50">Top50</ulink>
- map products available in Germany and Austria.
-</para>
-<para>
- This module supports binary overlay file format version 2.0, 3.0
- and 4.0. Those files can be identified by looking at the first
- bytes:
-</para>
-<programlisting>
-hexdump -C example.ovl | head -n 2
-00000000 44 4f 4d 47 56 43 52 44 20 4f 76 6c 66 69 6c 65 |DOMGVCRD Ovlfile|
-00000010 20 56 33 2e 30 3a 00 00 00 08 00 00 00 1e 00 00 | V3.0:..........|
-</programlisting>
-<para>
- The current file version 5.0 is not supported.
-</para>
+++ /dev/null
-<para>
- Overlay files used by <productname>Geogrid</productname>-Viewer has to be in ASCII format.
- Make sure you save the files correctly.
-</para>
-<para>
- Lines or polygons within the <productname>Geogrid</productname>-Viewer (type 3 and 4) will be
- converted to tracks, except they are grouped. In this case GPSBabel creates routes.
-</para>
-<para>
- During the creation of an overlay file, a circle will be added to each
- position of a waypoint or a route.
-</para>
-
-<para>
- Sample layout of the ASCII overlay file
- <programlisting format="linespecific">
- [Symbol <number # >]
- Typ=<1=picture,2=Text, 3=line, 4=area, 5=rectangle, 6=circle, 7=triangle>
- Group=<1=no group, number > 1=group number>
- Col=<number of the line color>
- Zoom=<1=no zoom, 2=zoom>
- Size=<size can be between 101 and 118>
- Art=<style>
- Punkte=<number of XKoord>
- XKoord0=<decimal X coordinate (Longitude) of the waypoint>
- YKoord0=<decimal Y coordinate (Latitude) of the waypoint>
- [MapLage]
- MapName=Top. Karte 1:50.000 Nieders.
- DimmFc=100
- ZoomFc=<zoom level of the map>
- CenterLat=<map center in decimal Y coordinates>
- CenterLong=<map center in decimal X coordinates of >
- RefOn=0
- </programlisting>
-</para>
-